package db

import (
	"fmt"
	"time"

	"migrate/app"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type Db struct {
	Config *app.DbConfig
	Db     *gorm.DB
}

func (d *Db) NewDb() (err error) {
	dsn := fmt.Sprintf(
		"%s:%s@tcp(%s:%d)/?charset=%s&parseTime=%s&loc=%s",
		d.Config.Username,
		d.Config.Password,
		d.Config.Host,
		d.Config.Port,
		d.Config.Charset,
		d.Config.ParseTime,
		d.Config.Loc,
	)

	d.Db, err = gorm.Open(mysql.New(mysql.Config{
		DSN:                       dsn,   // data source name
		DefaultStringSize:         256,   // default size for string fields
		DisableDatetimePrecision:  true,  // disable datetime precision, which not supported before MySQL 5.6
		DontSupportRenameIndex:    true,  // drop & create when rename index, rename index not supported before MySQL 5.7, MariaDB
		DontSupportRenameColumn:   true,  // `change` when rename column, rename column not supported before MySQL 8, MariaDB
		SkipInitializeWithVersion: false, // auto configure based on currently MySQL version
	}), &gorm.Config{})

	if err != nil {
		return
	}

	sqlDB, err := d.Db.DB()
	if sqlDB.Ping() != nil {
		return
	}

	if err != nil {
		return
	}

	// SetMaxIdleConns sets the maximum number of connections in the idle connection pool.
	sqlDB.SetMaxIdleConns(d.Config.MaxIdleConns)

	// SetMaxOpenConns sets the maximum number of open connections to the database.
	sqlDB.SetMaxOpenConns(d.Config.MaxOpenConns)

	// SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
	sqlDB.SetConnMaxLifetime(time.Hour)

	return
}

func (d *Db) Close() {
	sqlDB, _ := d.Db.DB()
	sqlDB.Close()
}
